{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from numba import njit"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def cmma(bar_data, lookback):\n",
    "\n",
    "    @njit  # Enable Numba JIT.\n",
    "    def vec_cmma(values):\n",
    "        # Initialize the result array.\n",
    "        n = len(values)\n",
    "        out = np.array([np.nan for _ in range(n)])\n",
    "\n",
    "        # For all bars starting at lookback:\n",
    "        for i in range(lookback, n):\n",
    "            # Calculate the moving average for the lookback.\n",
    "            ma = 0\n",
    "            for j in range(i - lookback, i):\n",
    "                ma += values[j]\n",
    "            ma /= lookback\n",
    "            # Subtract the moving average from value.\n",
    "            out[i] = values[i] - ma\n",
    "        return out\n",
    "\n",
    "    # Calculate with close prices.\n",
    "    return vec_cmma(bar_data.close)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pybroker\n",
    "\n",
    "cmma_20 = pybroker.indicator('cmma_20', cmma, lookback=20)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pybroker.ext.data import AKShare\n",
    "\n",
    "akshare = AKShare()\n",
    "df = akshare.query('000001', '4/1/2020', '4/1/2022')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cmma_20(df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cmma_20.iqr(df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cmma_20.relative_entropy(df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def buy_cmma_cross(ctx):\n",
    "    if ctx.long_pos():\n",
    "        return\n",
    "    # Place a buy order if the most recent value of the 20 day CMMA is < 0:\n",
    "    if ctx.indicator('cmma_20')[-1] < 0:\n",
    "        ctx.buy_shares = ctx.calc_target_shares(1)\n",
    "        ctx.hold_bars = 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pybroker import Strategy\n",
    "\n",
    "strategy = Strategy(AKShare(), '4/1/2020', '4/1/2022')\n",
    "strategy.add_execution(buy_cmma_cross, '000001', indicators=cmma_20)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "result = strategy.backtest(warmup=20)\n",
    "result.metrics_df.round(4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pybroker import highv\n",
    "\n",
    "def hhv(bar_data, period):\n",
    "    return highv(bar_data.high, period)\n",
    "\n",
    "hhv_5 = pybroker.indicator('hhv_5', hhv, period=5)\n",
    "hhv_5(df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pybroker import IndicatorSet\n",
    "\n",
    "indicator_set = IndicatorSet()\n",
    "indicator_set.add(cmma_20, hhv_5)\n",
    "indicator_set(df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import talib\n",
    "\n",
    "rsi_20 = pybroker.indicator('rsi_20', lambda data: talib.RSI(data.close, timeperiod=20))\n",
    "rsi_20(df)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Abroker",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
